#include "gfx_framebuffer.h"

#ifndef UGLY_HACK_FOR_THOSE_WHO_DONT_KNOW_HOWTO_INSTALL_SDL
#include <SDL/SDL.h>
#else
#include <SDL.h>
#endif

static GFX_Resolution _Resolution;
static SDL_Surface *_Ecran;

int gfx_set_resolution(GFX_Resolution res)
{
    int flags = SDL_DOUBLEBUF;
    if(res.fullscreen) flags |= SDL_FULLSCREEN;
    _Ecran = SDL_SetVideoMode(res.width, res.height, res.bpp, flags);

    if (_Ecran==NULL)
    {
         return -1;
    }
    _Resolution=res;
    return 0;
}

GFX_Resolution gfx_get_resolution()
{
    return _Resolution;
}


void gfx_scene_begin()
{
    SDL_FillRect(_Ecran, 0, 0);
}

Uint32 getpixel(SDL_Surface *surface, int x, int y)
{
    int bpp = surface->format->BytesPerPixel;
    /* Here p is the address to the pixel we want to retrieve */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
        return *p;
        break;

    case 2:
        return *(Uint16 *)p;
        break;

    case 3:
        if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
            return p[0] << 16 | p[1] << 8 | p[2];
        else
            return p[0] | p[1] << 8 | p[2] << 16;
        break;

    case 4:
        return *(Uint32 *)p;
        break;

    default:
        return 0;       /* shouldn't happen, but avoids warnings */
    }
}

void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
    int bpp = surface->format->BytesPerPixel;
    /* Here p is the address to the pixel we want to set */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
        *p = pixel;
        break;

    case 2:
        *(Uint16 *)p = pixel;
        break;

    case 3:
        if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
            p[0] = (pixel >> 16) & 0xff;
            p[1] = (pixel >> 8) & 0xff;
            p[2] = pixel & 0xff;
        } else {
            p[0] = pixel & 0xff;
            p[1] = (pixel >> 8) & 0xff;
            p[2] = (pixel >> 16) & 0xff;
        }
        break;

    case 4:
        *(Uint32 *)p = pixel;
        break;
    }
}

void gfx_scene_end()
{
    if(_Resolution.width == 2*VSCREEN_WIDTH && _Resolution.height == 2*VSCREEN_HEIGHT)
    {
        if(SDL_LockSurface(_Ecran) == 0)
        {
            for(int y = VSCREEN_HEIGHT-1; y >= 0; y--)
            {
                for(int x = VSCREEN_WIDTH-1; x >= 0; x--)
                {
                    Uint32 c = getpixel(_Ecran, x, y);
                    putpixel(_Ecran, x*2, y*2, c);
                    putpixel(_Ecran, x*2+1, y*2, c);
                    putpixel(_Ecran, x*2, y*2+1, c);
                    putpixel(_Ecran, x*2+1, y*2+1, c);
                }
            }
        }
        SDL_UnlockSurface(_Ecran);
    }
    SDL_Flip(_Ecran);
}

void gfx_clipping_set(float x, float y, float w, float h)
{
    SDL_Rect rect = {x, y, w, h} ;
    SDL_SetClipRect(_Ecran, &rect);
}

void gfx_clipping_reset(void)
{
    SDL_SetClipRect(_Ecran, 0);
}
